﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;


namespace libcontrol
{
    class KamoerPump
    {
        public SerialPortHelper Kamoer485Port=null;
        public  byte[] CmdStart    = new byte[] { 0xc0 ,0xf ,0x10 ,0x1 ,0x0 ,0x1 ,0x0 ,0x1 ,0x1c ,0x0b }; //开始转动
        public  byte[] CmdStop     = new byte[] { 0xc0 ,0xf ,0x10 ,0x1 ,0x0 ,0x1 ,0x0 ,0x0 ,0xdd ,0xcb }; //停止转动
        public byte[] Cmd485Enable = new byte[] { 0xc0 ,0xf ,0x10 ,0x4 ,0x0 ,0x1 ,0x0 ,0x1 ,0xd0 ,0x0b };
        public byte[] Cmd485Diable = new byte[] { 0xc0 ,0xf ,0x10 ,0x4, 0x0, 0x1 ,0x0 ,0x0 ,0x11, 0xcb };
        public byte[] Cmd485CW     = new byte[] { 0xc0 ,0xf,0x10  ,0x3, 0x0 ,0x1 ,0x0 ,0x0 ,0xa4, 0x0b };
        public byte[] Cmd485CCW    = new byte[] { 0xc0 ,0xf,0x10  ,0x3, 0x0 ,0x1 ,0x0, 0x1, 0x65 ,0xcb };

        public static byte[] CRC16(byte[] data)
        {
            int len = data.Length;
            if (len > 0)
            {
                ushort crc = 0xFFFF;

                for (int i = 0; i < len; i++)
                {
                    crc = (ushort)(crc ^ (data[i]));
                    for (int j = 0; j < 8; j++)
                    {
                        crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                    }
                }
                byte hi = (byte)((crc & 0xFF00) >> 8);  //高位置
                byte lo = (byte)(crc & 0x00FF);         //低位置

                return new byte[] { hi, lo };
            }
            return new byte[] { 0, 0 };
        }

        byte[] GetSpeedCmd(string strSpeed)
        {
            byte[] SpeedCmdHead = new byte[11] { 0xc0, 0x10, 0x30, 0x1, 0x0, 0x2, 0x4, 0x43, 0x2a, 0x0, 0x0 };
            try
            {
                var nSpeed = (float)int.Parse(strSpeed);
                byte[] FloatByte = BitConverter.GetBytes(nSpeed);

                for (var i = 0; i < 4; i++)
                {
                    SpeedCmdHead[7 + i] = FloatByte[3-i];
                }

                byte[] CrcByte = CRC16(SpeedCmdHead);

                byte[] AllCmd = new byte[13];
                for (var i = 0; i < 11; i++)
                {
                    AllCmd[i] = SpeedCmdHead[i];
                }

                AllCmd[11] = CrcByte[1];
                AllCmd[12] = CrcByte[0];
                string _strAllCmd = string.Empty;
                for (int i = 0; i < 13; i++)
                {
                    _strAllCmd += String.Format("{0:X2} ", AllCmd[i]);
                }

                return AllCmd;

            }
            catch(Exception ex)
            {
            }

            return null;
        }

        /// <summary>
        /// 连接点水器,
        /// </summary>
        /// <param name="nPort"></param>
        bool Connect(string strComPort)
        {
            if(Kamoer485Port==null)
            {
                Kamoer485Port = new SerialPortHelper();
                Kamoer485Port.serialPort.BaudRate = 9600;
                Kamoer485Port.serialPort.PortName = strComPort;
                Kamoer485Port.serialPort.DataBits = 8;
                Kamoer485Port.serialPort.StopBits = StopBits.One;
                Kamoer485Port.serialPort.Parity = Parity.None;
                Kamoer485Port.serialPort.ReadTimeout = 30000;
                Kamoer485Port.Open();

                if(Kamoer485Port.IsOpen)
                {
                    Kamoer485Port.DataReceived += Kamoer485Port_DataReceived;
                    return true;
                }
            }

            return false;
        }

        private void Kamoer485Port_DataReceived(byte[] readBuffer)
        {
           // Log.Debug(Encoding.Default.GetString(readBuffer));
        }

        byte[] GetDirCmd(string strDir)
        {
            if(strDir=="CW")
            {
                return Cmd485CW;
            }

            return Cmd485CCW;
        }


        public void InitKamoerPump()
        {
            try
            {
                //var _Config = DeviceConfig.GetInstance();
                Connect("COM3");
                Thread.Sleep(100);
                SendMsg(_KamoerPump.Cmd485Enable);
                Thread.Sleep(100);
                SendMsg(GetSpeedCmd("9"));
                Thread.Sleep(100);
                SendMsg(GetDirCmd("CW"));
                Thread.Sleep(100);
                SendMsg(CmdStart);
                IsInit = true;
            
            }
            catch(Exception ex)
            {
                //MessageBox.Show("蠕动泵通讯异常:"+ex.ToString()); 
            }
        }

        static KamoerPump _KamoerPump=new KamoerPump();
        static bool IsInit = false;
        /// <summary>
        /// 使能485 设置速度,转动点水机,方向
        /// </summary>
        public static void Init()
        {
            new Thread(new ThreadStart(_KamoerPump.InitKamoerPump)).Start();
        }

        void StopRun()
        {
            SendMsg(CmdStop);
            Thread.Sleep(50);  //等待数据回传 

            if(Kamoer485Port==null)
            {
                return;
            }
            
            if(Kamoer485Port.IsOpen)
            {
                Kamoer485Port.Close();
            }
        }

        /// <summary>
        /// 停止电机转动 关闭串口
        /// </summary>
        public static void Close()
        {
            if(IsInit)
            {
                _KamoerPump.StopRun();
            }
                 
        }


        void SendMsg(byte[] _Cmd)
        {
            Kamoer485Port.WritePort(_Cmd, 0, _Cmd.Length);
        }
    }
}
